$(document).ready(function() {
  // Clock variables.
  var date, clock_interval, t;
  
  // Concerto variables.
  var concerto_interval, cw, c_feed = window.c_feed, c_feed_len = window.c_feed_len, c_i;

  // Schedule variables.
  var s_changing = false, s_queued = false, s_state, s_last_state, s_full, s_today, s_weekly_data, s_monthly_data, s_empty, s_is_first_week, s_is_last_week, s_current_week, s_this_week, s_current_week_index, s_weeks = [];
  
  // Search variables.
  var q_keyboard_active = false, q_val, that, q_active = false, q_wrapper_h, q_results_h, q_at_top, q_at_bottom, q_pos;
  
  // Renders the current time.
  function drawClock() {
    var h24, h12, m, ampm;
    
    date = new Date();
  
    // Get the time.
    h24 = date.getHours();
    m = date.getMinutes();
    
    // Convert to 12-hour time.
    h12 = h24 % 12;
    if (h12 == 0) {
      h12 = 12;
    }
    
    // Add a leading zero to single digit minutes. 
    if (m < 10) {
      m = '0' + m;
    }
    
    // Set the am/pm value.
    ampm = 'pm';
    if (h24 < 12) {
      ampm = 'am';
    }
    
    t.text(h12 + ':' + m + ampm)
  }
  
  // Fetches new Concerto feed items.
  function fetchConcertoFeed() {
    // Waiting for a new view to be added so we can update this dynamically.
    c_feed = [['5162', 'Rickroll - WRPI'], ['5166', '4.2.10 RPAlert System Test'], ['5173', 'W2SZ Advert'], ['5177', 'India in January 2011'], ['5183', 'Video Contest'], ['5246', 'Textbooks Expensive']];
    
    
    // TODO: Make this pull from the actual Community feed.
    
    c_feed_len = c_feed.length;
  }
  
  // Animation for the Concerto feed.
  function animateConcerto() {
    // Add a new item to the feed.
    c_i = (c_i + 1) % c_feed_len;
    $('#concerto-wrapper').append('<li><img src="http://concerto.rpi.edu/content/render/index.php?width=630&height=600&select=content&select_id=' + c_feed[c_i][0] + '&format=raw" alt="' + c_feed[c_i][1] + '" /></li>');

    // Fade out the top item in the feed.
    $('#concerto-wrapper li:first-child').animate({opacity: 0.0, height: 0, marginBottom: 0}, 2000, function() {
      // Remove it from the DOM, so the next concerto element uses the first-child styles.
      $('#concerto-wrapper li:first-child').detach();
    });
    
  }
  
    // Transitions the schedule to the daily (default) view.
  function transitionToDaily() {
    // If we had the search results active, remove them.
    if ($('#search-results').get(0) != undefined) {
      $('#search-results').empty();
      $('#search-results').attr('id', 'timeline');
    }
  
    // Transition out of full schedule mode and reanimate Concerto.
    if (s_full) {
      transitionFromFullSchedule();
      return false;
    }
    
    // Fade in the daily schedule.
    $.ajax({
      url: 'http://senatedev.union.rpi.edu/mmdk/rails/locations/1/events/today/',
      success: function(data) {
        $('#timeline').html(data);
      }
    });
    
    $('#timeline').fadeIn(1000);
    s_changing = false;
  }
  
  // Transitions to the weekly schedule view.
  function transitionToWeekly(week) { 
    // Transition to full schedule mode.
    if (!s_full) {
      transitionToFullSchedule('weekly', week);
      return false;
    } else if (!s_empty) {
      // Clear out the contnet.
      $('#coverflow').fadeOut(500, function() {
        $('#coverflow').empty();
        s_empty = true;
        transitionToWeekly(week);
      });
      
      return false;
    }
    
    $('#coverflow').empty();
    // Check to see if we're requesting to look at a specific week.
    if (week != undefined) {
      s_current_week = week;
    } else {
      s_current_week = s_this_week;
    }
    s_current_week_index = s_weeks.indexOf(s_current_week);
    weekText = s_current_week.split('-');
    $('#coverflow').append('<h2>Week of ' + weekText[1] + '/' + weekText[2] + '</h2>');
    request_url = "locations/1/events/weekly/2010/" + weekText[1] + "/" + weekText[2];
    $.ajax({ url: request_url, context: document.body, success: function(data){
      weekData = data;
    
      // TODO: Something that actually renders data dynamically.
      $('#coverflow').removeClass('monthly-schedule').addClass('weekly-schedule').append(weekData);
      s_empty = false;
    
      // Configure the pagination buttons.
      $('#pagination > li').removeClass('unavailable');
      if (isFirstWeek()) {
        // Make the back button transparent.
        $('#pagin-left').addClass('unavailable');
      }
      if (isLastWeek()) {
        // Make the next button transparent.
        $('#pagin-right').addClass('unavailable');
      }
    
      // Fade in the weekly schedule.
      $('#coverflow').fadeIn(1000);
      $('#pagination').fadeIn(1000);
      s_changing = false;
    }});
  }
  
  // Transistions to the monthly schedule view.
  function transitionToMonthly() {
    // Transition to full schedule mode.
    if (!s_full) {
      transitionToFullSchedule('monthly');
      return false;
    } else if (!s_empty) {
      // Clear out the contnet.
      $('#pagination').fadeOut(200);
      $('#coverflow > *').fadeOut(200, function() {
        $('#coverflow').empty();
        s_empty = true;
        transitionToMonthly();
      });
      
      return false;
    }
    
    // TODO: Something that actually renders data dynamically.
    $('#coverflow').removeClass('weekly-schedule').addClass('monthly-schedule').append(s_monthly_data);
    s_empty = false;
    
    // Add mousedown event handlers to each of the weeks to allow a transition to weekly view for that particular week.
    $('.monthly-schedule > li').bind({
      mousedown: function() {
        var s_id = 'schedule-w';
        $('#'+s_state).removeClass('selected');
        $('#schedule-w').addClass('selected');
        s_last_state = s_state;
        s_state = s_id;
        transitionToWeekly($(this).attr('id'));
      }
    });
    
    // Fade in the weekly schedule.
    $('#coverflow').fadeIn(1000);
    s_changing = false;
  }
  
  // Transitions the schedule to full screen mode.
  function transitionToFullSchedule(caller, opt) {
    // Pause the Concerto feed.
    pauseConcerto();
    
    // Kill the search results.
    if ($('#search-results').get(0) != undefined) {
      $('#search-results').empty();
      $('#search-results').attr('id', 'timeline');
    }
    
    // Fade out the timeline.
    $('#timeline').fadeOut(200);
    $('#mv-schedule').animate({width: '100%'}, 750, function() {
      s_full = true;
      
      if (caller == 'weekly') {
        transitionToWeekly(opt);
      } else if (caller == 'monthly') {
        transitionToMonthly();
      }
    });
    $('#search').animate({marginRight: '0.65%'}, 200);
  }
  
  // Transitions out of full screen mode.
  function transitionFromFullSchedule() {
    $('#pagination').fadeOut(200);
    $('#coverflow').fadeOut(200, function() {
      $('#coverflow').empty();
      s_empty = true;
    });
    $('#mv-schedule').animate({width: '50%'}, 750, function() {
      s_full = false;
      
      // Show today's schedule if we're not about to display search results.
      if (!q_active) {
        transitionToDaily();
      } else {
        $('#search-results').fadeIn(200);
      }
    });
    $('#search').animate({marginRight: '9.8%'}, 200);
    
    // Reanimate Concerto.
    resumeConcerto();
  }
  
  // Checks to see if this is the first/current week.
  function isFirstWeek(week) {
    week = week ? week : s_current_week;
  
    s_is_first_week = week == s_weeks[0];
    return s_is_first_week;
  }
  
  // Checks to see if this is the last week.
  function isLastWeek(week) {
    week = week ? week : s_current_week;
  
    s_is_last_week =  week == s_weeks[s_weeks.length-1];
    return s_is_last_week;
  }
  
  // Pauses the Concerto feed animation.
  function pauseConcerto(hide) {
    if (!hide) {
      $('#mv-concerto').fadeOut(400);
    }
    
    clearInterval(concerto_interval);
    concerto_interval = -1;
  }
  
  // Resume the Concerto feed animation.
  function resumeConcerto() {
    $('#mv-concerto').fadeIn(400);
    
    if (concerto_interval == -1) {
      concerto_interval = setInterval(function() {return animateConcerto();}, 8000);
    }
  }
  
  // Fetches search results.
  function fetchSearchResults() {
    // TODO: Take search box text and ajax it to the server.
    $.ajax({
      url: 'http://senatedev.union.rpi.edu/mmdk/rails/events/search?query=' + $('#search-box').val(),
      success: function(data) {
        // Let's just pretend these are real search results for now.
        $('#search-results').html(data);
      
        // Format the search wrapper.
        $('#results-wrapper').css('height', (window.innerHeight-243) + 'px');
        $('#scroll-down').css('top', (parseInt($('#search-results').css('height')) + 45) + 'px');
        
        // Configure the scroll buttons.
        q_at_top = true;
        q_at_bottom = true;
        q_pos = 0;
        
        q_wrapper_h = parseInt($('#results-wrapper').css('height'));
        q_results_h = parseInt($('#results-wrapper > ul').css('height'));
        if (q_results_h > q_wrapper_h) {
          $('#scroll-down').removeClass('unavailable');
          q_at_bottom = false;
        }
        
        // Bind the mousedown actions to the buttons.
        $('#scroll-up').bind({
          mousedown: function() {
            // Don't do any scrolling if we're at the top.
            if (q_at_top) {
              return false;
            }
            
            // Calculate position and state changes.
            q_pos = Math.min(0, q_pos + 450);
            if (q_pos == 0) {
              q_at_top = true;
              $('#scroll-up').addClass('unavailable');
            }
            if (q_pos != -1 * (q_results_h - q_wrapper_h)) {
              q_at_bottom = false;
              $('#scroll-down').removeClass('unavailable');
            }
            
            // Animate the scroll.
            $('#results-wrapper > ul').animate({top: q_pos + 'px'}, 500);
          }
        });
        $('#scroll-down').bind({
          mousedown: function() {
            // Don't do any scrolling if we're at the top.
            if (q_at_bottom) {
              return false;
            }
            
            // Calculate position and state changes.
            q_pos = Math.max(-1 * (q_results_h - q_wrapper_h), q_pos - 450);
            if (q_pos != 0) {
              q_at_top = false;
              $('#scroll-up').removeClass('unavailable');
            }
            if (q_pos == -1 * (q_results_h - q_wrapper_h)) {
              q_at_bottom = true;
              $('#scroll-down').addClass('unavailable');
            }

            // Animate the scroll.
            $('#results-wrapper > ul').animate({top: q_pos + 'px'}, 500);
          }
        });
      
        // Attach an event to make the 'Back to Schedule' button functional.
        $('#backToSchedule').bind({
          mousedown: function() {
            // Clear the search box.
            $('#search-box').val('');
            $('#search-box').trigger('blur');
          
            // Return to the schedule.
            $('#'+s_state).trigger('mousedown');
          }
        });
      }
    });
  }
  
  // Initialize the interaction for the search field.
  function initSearch() {
    // Reset the keyboard's position if the screen width isn't 1366x768.
    $('#keyboard').css('left', ((screen.width - 840) / 2) - 2);
  
    $('#keyboard').bind({
      mouseenter: function() {
        q_keyboard_active = true;
      },
      mouseleave: function() {
        q_keyboard_active = false;
        $('#search-box').trigger('blur');
      }
    });
    
    // Add mousedown events to the keyboard to allow it to update the text field.
    $('#keyboard > li > ul > li').bind({
      mousedown: function() {
        // Check to see if this is a special key (search, space, backspace).
        if ($(this).attr('id') == 'keyboard-space') {
          q_val += ' ';
        } else if ($(this).attr('id') == 'keyboard-backspace') {
          q_val = q_val.substring(0, q_val.length - 1);
          
          // Do a live search.
          if (q_val.length > 0) {
            // Clear out the daily schedule and stuff, if applicable.
            if ($('#search-results').get(0) == undefined) {
              s_today = $('#timeline').html();
              $('#timeline').html('');
              $('#timeline').attr('id', 'search-results');
              
              // Reset the schedule buttons and switch from full screen.
              q_active = true;
              $('#'+s_state).removeClass('selected');
              if (s_state != 'schedule-d') {
                transitionFromFullSchedule();
              }
            }
            
            // Grab some search results, asynchronously.
            setTimeout(function() {fetchSearchResults();}, 10);
          }
        } else if ($(this).attr('id') == 'keyboard-go') {
          q_keyboard_active = false;
          $('#search-box').trigger('blur');
          
          // Clear out the daily schedule.
          s_today = $('#timeline').html();
          $('#timeline').html('');
          $('#timeline').attr('id', 'search-results');
          
          // Reset the schedule buttons and switch from full screen.
          q_active = true;
          $('#'+s_state).removeClass('selected');
          if (s_state != 'schedule-d') {
            transitionFromFullSchedule();
          }
          
          // Grab some search results, asynchronously.
          setTimeout(function() {fetchSearchResults();}, 10);
          
          return false;
        } else {
          q_val += $(this).text().toLowerCase();
          
          // Do a live search.
          if (q_val.length > 0) {
            // Clear out the daily schedule and stuff, if applicable.
            if ($('#search-results').get(0) == undefined) {
              s_today = $('#timeline').html();
              $('#timeline').html('');
              $('#timeline').attr('id', 'search-results');
              
              // Reset the schedule buttons and switch from full screen.
              q_active = true;
              $('#'+s_state).removeClass('selected');
              if (s_state != 'schedule-d') {
                transitionFromFullSchedule();
              }
            }
            
            // Grab some search results, asynchronously.
            setTimeout(function() {fetchSearchResults();}, 10);
          }
        }  
        
        // Update the text in the search box.
        $('#search-box').val(q_val);
      }
    });
  
    $('#search-box').bind({
      blur: function() {
        // Don't follow through with blurring if the keyboard is active.
        if (q_keyboard_active) { 
          return false;
        }
      
        // Fade the text.
        $('#search-box').addClass('placeholder');
        
        // Hide the keyboard.
        $('#keyboard').animate({bottom: -600}, 800);
        
        // Resume Concerto only if we're on the daily schedule.
        if (!s_full) {
          resumeConcerto();
        }
        
        // If no content in the box, fill with the default.
        if ($.trim($('#search-box').val()) == '') {
          // Adds the default text.
          $('#search-box').val('Find an Event or Room')
        }
      },
      
      focus: function() {
        if ($('#search-box').val() == 'Find an Event or Room') {
          // Default text, clear it out.
          $('#search-box').val('')
        }
        
        // Update the style.
        $('#search-box').removeClass('placeholder');
        q_val = $('#search-box').val();
        
        // Bring up the keyboard.
        $('#keyboard').animate({bottom: 0}, 800);
        
        // Pause Concerto only if we're on the daily schedule.
        if (!s_full) {
          pauseConcerto(true);
        }
        
      }
    });
    
  }
  
  // Initialize the clock.
  function initClock() {
    t = $('#time');
    
    // Initally render the clock, and set it to update.
    drawClock();
    clock_interval = setInterval(function() {return drawClock();}, 1000);
  }
  
  // Initializes the Concerto content feed.
  function initConcerto() {
    var i;
  
    c = $('#concerto-wrapper');
    
    // Get a Concerto feed, if we don't have one.
    if (c_feed == undefined) {
      fetchConcertoFeed();
    }
    
    // Do the initial rendering.
    c_i = 0;
    // Add 3 items to the display feed.
    for (i=0; i<3; ++i) {
      c_i = (c_i + 1) % c_feed_len;
      $('<li><img src="http://concerto.rpi.edu/content/render/index.php?width=630&height=600&select=content&select_id=' + c_feed[c_i][0] + '&format=raw" alt="' + c_feed[c_i][1] + '" /></li>').prependTo('#concerto-wrapper');
    }
    
    // Set it to animate.
    concerto_interval = setInterval(function() {return animateConcerto();}, 8000);
  }
  
  // Initalizes the interactions for the schedule.
  function initSchedule() {
    // Set the initial state.
    s_this_week = '';
    s_state = 'schedule-d';
    s_full = false;
    s_empty = true;
    
    // Load in some data.
    s_weekly_data = ''
    s_monthly_data = '';
    
    // Load in Today's schedule.
    $.ajax({
      url: 'http://senatedev.union.rpi.edu/mmdk/rails/locations/1/events/today/',
      success: function(data) {
        $('#timeline').html(data);
      }
    });
    
    // Load in the upcoming weeks.
    $.ajax({
      url: 'http://senatedev.union.rpi.edu/mmdk/rails/events/weeks/',
      dataType: 'json',
      success: function(data) {
        var i, len, sun, sat, tmp = [], week_val;
        
        for (i=0, len=data.length; i<len; i+=2) {
          // Parse to remove leading zeroes.
          sun = data[i].replace(/-0/g, '-');
          sat = data[i+1].replace(/-0/g, '-');
        
          // Split up the dates.
          sun = sun.split('-');
          sat = sat.split('-');
           
          // Update weeks.
          week_val = 'wlink-' + sun[1] + '-' + sun[2]
          s_weeks.push(week_val);
          
          // Add to the monthly display.
          tmp.push('<li id="' + week_val + '">' + sun[1] + '/' + sun[2] + ' - ' + sat[1] + '/' + sat[2] + '<span>&raquo;</span></li>');
        }
        
        // Finalize the data.
        s_this_week = s_weeks[0];
        s_monthly_data = '<h2>Select a Week</h2>' + tmp.join('');
      }
    });
    
    // Handle interaction for mousedowning on the schedule buttons.
    $('#schedule-opts > li').bind({
      mousedown: function() {
        // Make sure we're not already transitioning.
        if (s_changing && !s_queued) {
          s_queued = true;
          // Try to run the transition after this transition finishes.
          that = $(this);
          setTimeout(function() {s_queued = false; that.trigger('mousedown');}, 1000);
          return false;
        } else if (s_queued) {
          return false;
        }
        s_changing = true;
        s_queued = false;
        
        var s_id = $(this).attr('id');

        // Check to make sure we're not trying to reload the current view.
        if (s_id != s_state || q_active) {
          // Update the button styles.
          $('#'+s_state).removeClass('selected');
          $(this).addClass('selected');
          s_last_state = s_state;
          s_state = s_id;
          q_active = false;

          // Transition to the appropriate state.
          if (s_state == 'schedule-d') {
            transitionToDaily();
          } else if (s_state == 'schedule-w') {
            transitionToWeekly();
          } else if (s_state == 'schedule-m') {
            transitionToMonthly();
          }
        }
      }
    });
    function triggerClick(x) {
      x.trigger('mousedown');
    }
    // Handle interaction for the pagination buttons in the weekly view.
    $('#pagination > li').bind({
      mousedown: function() {
        var mousedown_id = $(this).attr('id');
        
        // Transition to the previous week if applicable.
        if (mousedown_id == 'pagin-left' && !s_is_first_week) {
          transitionToWeekly(s_weeks[--s_current_week_index]);
        }
        
        // Transition to the next week if applicable.
        if (mousedown_id == 'pagin-right' && !s_is_last_week) {
          transitionToWeekly(s_weeks[++s_current_week_index]);
        }
      }
    });
  }
  
  // Initializes the dashboard.
  function init() {
    // Set the interactions for the search box.
    initSearch();
    
    // Get the clock running.
    initClock();
    
    // Start the Concerto feed.
    initConcerto();
    
    // Initialize the schedule.
    initSchedule();
  };
  
  init();
});
